﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ITAP.Core.Modelling.Primitives;
using ITAP.Core.Calculations;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.Components
{
    [Serializable]
    public abstract class EndedContourComponent : ContourComponent, IEndedContourComponent
    {

        #region IEndedContourComponent Members

        public virtual ModelPoint StartPoint
        {
            get
            {
                return ((IEndedPrimitive)this.Primitive).StartPoint;
            }
        }

        public virtual ModelPoint EndPoint
        {
            get { return ((IEndedPrimitive)this.Primitive).EndPoint; }
        }

        public virtual IContourComponent ConnectTo(IContourComponent component, EndType endOfThisComponentToConnect)
        {
            if (this.connectedComponents.Contains(component))
                return null;

            switch (endOfThisComponentToConnect)
            {
                case EndType.Start:
                    if (this.StartConnectedComponent == null)
                    {
                        this.connectedComponents.Add(component);
                        this.startConnectedComponent = component;
                        return this;
                    }
                    else
                    {
                        if (!this.RemoveInnerComponent(this.startConnectedComponent))
                            ContourConnectionProvider.Disconnect(this, this.startConnectedComponent);

                        this.startConnectedComponent = component;
                        this.connectedComponents.Add(component);
                        return this;
                    }
                case EndType.End:
                    if (this.EndConnectedComponent == null)
                    {
                        this.connectedComponents.Add(component);
                        this.endConnectedComponent = component;
                        return this;
                    }
                    else
                    {
                        if (!this.RemoveInnerComponent(this.endConnectedComponent))
                            ContourConnectionProvider.Disconnect(this, this.endConnectedComponent);

                        this.endConnectedComponent = component;
                        this.connectedComponents.Add(component);
                        return this;
                    }
            }
            return null;

        }

        public virtual double Length
        {
            get { return ((IEndedPrimitive)this.Primitive).Length; }
        }

        public virtual void SetLength(double length, EndedPrimitivePoints endPoint)
        {
            ((IEndedPrimitive)this.Primitive).SetLength(endPoint, length);
        }

        public virtual double Height
        {
            get
            {
                return ((IEndedPrimitive)this.Primitive).Height;
            }
            set
            {
                ((IEndedPrimitive)this.Primitive).Height = value;
            }
        }

        public virtual bool IsHalfRound
        {
            get
            {
                if (this.Primitive is IEndedCurvedPrimitive)
                {
                    IEndedCurvedPrimitive curvedPrimitive = this.Primitive as IEndedCurvedPrimitive;
                    return curvedPrimitive.IsHalfRound;
                }
                else
                {
                    return false;
                }
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        protected IContourComponent startConnectedComponent;
        public IContourComponent StartConnectedComponent
        {
            get { return startConnectedComponent; }
        }

        protected IContourComponent endConnectedComponent;
        public IContourComponent EndConnectedComponent
        {
            get { return endConnectedComponent; }
        }

        #endregion

        #region IEndPointsMoveable Members

        public virtual void MoveStartPoint(ModelPoint destination)
        {
            ((IEndedPrimitive)this.Primitive).MoveStartPoint(destination);
        }

        public virtual void MoveEndPoint(ModelPoint destination)
        {
            ((IEndedPrimitive)this.Primitive).MoveEndPoint(destination);
        }

        public virtual void MoveCenterPoint(ModelPoint destination)
        {
            throw new NotImplementedException();
        }

        public virtual void MoveStartPoint(ModelVector offset)
        {
            throw new NotImplementedException();
        }

        public virtual void MoveEndPoint(ModelVector offset)
        {
            throw new NotImplementedException();
        }

        public virtual void MoveCenterPoint(ModelVector offset)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IRotateable Members

        public virtual void Rotate(Angle angle, ModelPoint rotateCenter)
        {
            this.Primitive.Rotate(rotateCenter, angle.Value);
        }

        #endregion
    }
}
